﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PengSW.XmlDb;
using System.Xml.Linq;
using System.Xml.XPath;

namespace PengSW.XmlDb
{
    public class XmlDbRuleToDB2 : XmlDbRule
    {
        public string CreateSql(XmlToFieldRule aFieldRule)
        {
            return string.Format("{0} {1} {2}", aFieldRule.FieldName, aFieldRule.DataType, aFieldRule.NotNull ? "NOT NULL" : "");
        }

        public string GetDropTableSql(XmlToTableRule aTableRule)
        {
            System.Text.StringBuilder aSqlBuilder = new System.Text.StringBuilder();
            aSqlBuilder.AppendLine(string.Format("DROP TABLE {0};", aTableRule.TableName));

            foreach (XmlToTableRule aSubTableRule in aTableRule.SubTableRules)
            {
                aSqlBuilder.AppendLine(GetDropTableSql(aSubTableRule));
            }
            return aSqlBuilder.ToString();
        }

        public string GetCreateTableSql(XmlToTableRule aTableRule)
        {                
            System.Text.StringBuilder aSqlBuilder = new System.Text.StringBuilder();
            aSqlBuilder.Append(string.Format("CREATE TABLE {0} (", aTableRule.TableName));
            foreach (XmlToFieldRule aFieldRule in aTableRule.FieldRules)
            {
                aSqlBuilder.Append(string.Format("{0}, ", CreateSql(aFieldRule)));
            }
            aSqlBuilder.AppendLine(string.Format("CONSTRAINT ID PRIMARY KEY ({0}));", aTableRule.IdFieldName));

            foreach (XmlToTableRule aSubTableRule in aTableRule.SubTableRules)
            {
                aSqlBuilder.AppendLine(GetCreateTableSql(aSubTableRule));
            }
            return aSqlBuilder.ToString();
        }

        public string FieldNames(XmlToTableRule aTableRule)
        {
            System.Text.StringBuilder aStringBuilder = new System.Text.StringBuilder();
            foreach (XmlToFieldRule aFieldRule in aTableRule.FieldRules)
            {
                aStringBuilder.Append(string.Format("{0}, ", aFieldRule.FieldName));
            }
            aStringBuilder.Length -= 2;
            return aStringBuilder.ToString();
        }

        public string Values(XmlToTableRule aTableRule, XElement aRecordXElement, out string aId, string aParentId)
        {
            aId = PengSW.Id.UniqueId.GetSId();
            System.Text.StringBuilder aStringBuilder = new System.Text.StringBuilder();
            foreach (XmlToFieldRule aFieldRule in aTableRule.FieldRules)
            {
                string aValue = "";
                if (aFieldRule.FieldName == aTableRule.IdFieldName)
                {
                    aValue = aId;
                }
                else if (aFieldRule.FieldName == aTableRule.ParentIdFieldName)
                {
                    aValue = aParentId;
                }
                else if (aFieldRule.XPath.Trim() != string.Empty)
                {
                    XElement aFieldXElement = aRecordXElement.XPathSelectElement(aFieldRule.XPath);
                    aValue = aFieldXElement == null ? aFieldRule.DefaultValue : aFieldXElement.Value;
                }
                aStringBuilder.Append(aFieldRule.NeedQuot ? string.Format("'{0}', ", aValue) : string.Format("{0}, ", aValue));
            }
            aStringBuilder.Length -= 2;
            return aStringBuilder.ToString();
        }

        public string GetInsertSql(XmlToTableRule aTableRule, XElement aRecordXElement, out string aId, string aParentId)
        {
            return string.Format("INSERT INTO {0} ({1}) VALUES({2})", aTableRule.TableName, FieldNames(aTableRule), Values(aTableRule, aRecordXElement, out aId, aParentId));
        }
    }
}
